bitkeeper revision 1.1159.1.141 (413f74fcTwJtxfSqPOLD17o7tsdJbg)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Wed, 8 Sep 2004 21:09:16 +0000 (21:09 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Wed, 8 Sep 2004 21:09:16 +0000 (21:09 +0000)
Freed PTEs now pass through the TLB-gathering mechanism, as is correct.
We hook them back off into the pte caching allocator using the
SetForeignHeap() mechanism that I added for the network backend.

linux-2.6.8.1-xen-sparse/arch/xen/Kconfig
linux-2.6.8.1-xen-sparse/arch/xen/configs/xenU_defconfig
linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/pgtable.c
linux-2.6.8.1-xen-sparse/include/asm-xen/asm-i386/pgalloc.h

index 5beabc830dc38ce82630c54496c50396bf1e436f..2bbe0229b46c8b1ca16b2bbb8b5fbbe12b154bf5 100644 (file)
@@ -45,8 +45,7 @@ endmenu
 
 config FOREIGN_PAGES
        bool
-       default y if XEN_PHYSDEV_ACCESS
-       default n if !XEN_PHYSDEV_ACCESS
+       default y
 
 config PAGESIZED_SKBS
        bool
index 70e8811692551c683aff412bed82ec8919375595..8d0d9fc5a308e906859de1a12a9d4e474095b1d9 100644 (file)
@@ -11,7 +11,7 @@ CONFIG_NO_IDLE_HZ=y
 # CONFIG_XEN_PRIVILEGED_GUEST is not set
 # CONFIG_XEN_PHYSDEV_ACCESS is not set
 CONFIG_XEN_WRITABLE_PAGETABLES=y
-# CONFIG_FOREIGN_PAGES is not set
+CONFIG_FOREIGN_PAGES=y
 # CONFIG_PAGESIZED_SKBS is not set
 CONFIG_X86=y
 # CONFIG_X86_64 is not set
index bebd04f92dfb4bd3d28f93890ae68c79faa0d7aa..4516df164330ddafe8b575c04459120da28ad64e 100644 (file)
@@ -187,6 +187,9 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 
 void pte_ctor(void *pte, kmem_cache_t *cache, unsigned long unused)
 {
+       struct page *page = virt_to_page(pte);
+       SetPageForeign(page, pte_free);
+       set_page_count(page, 1);
 
        clear_page(pte);
        __make_page_readonly(pte);
@@ -196,6 +199,8 @@ void pte_ctor(void *pte, kmem_cache_t *cache, unsigned long unused)
 
 void pte_dtor(void *pte, kmem_cache_t *cache, unsigned long unused)
 {
+       struct page *page = virt_to_page(pte);
+       ClearPageForeign(page);
 
        queue_pte_unpin(virt_to_phys(pte));
        __make_page_writable(pte);
@@ -225,6 +230,20 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
        return NULL;
 }
 
+void pte_free(struct page *pte)
+{
+       set_page_count(pte, 1);
+#ifdef CONFIG_HIGHPTE
+       if (pte < highmem_start_page)
+#endif
+               kmem_cache_free(pte_cache,
+                               phys_to_virt(page_to_pseudophys(pte)));
+#ifdef CONFIG_HIGHPTE
+       else
+               __free_page(pte);
+#endif
+}
+
 void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags)
 {
        memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
index 3d36223ecad25e0426b66e6f33b986cfbfedc440..559df16eac2fbeee56d43cbe3045830b60ee3cd7 100644 (file)
@@ -36,21 +36,9 @@ static inline void pte_free_kernel(pte_t *pte)
        flush_page_update_queue();
 }
 
-static inline void pte_free(struct page *pte)
-{
-#ifdef CONFIG_HIGHPTE
-       if (pte < highmem_start_page)
-#endif
-               kmem_cache_free(pte_cache,
-                               phys_to_virt(page_to_pseudophys(pte)));
-#ifdef CONFIG_HIGHPTE
-       else
-               __free_page(pte);
-#endif
-}
-
+extern void pte_free(struct page *pte);
 
-#define __pte_free_tlb(tlb,pte)                pte_free(pte)
+#define __pte_free_tlb(tlb,pte)        tlb_remove_page((tlb),(pte))
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is